#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#include <pthread.h>

int phil_count = 5, max_table = 4, curr_table = 0;
sem_t forks[5], mutex;

void pick_forks(int id) {
	int tmpid = (id + 1)%phil_count;
	if (id%2 == 0) {
		sem_wait(&forks[tmpid]);
		printf("Filozof nr %d podniosl widelec nr %d\n", id, tmpid);
		sem_wait(&forks[id]);
		printf("Filozof nr %d podniosl widelec nr %d\n", id, id);
	} else {
		sem_wait(&forks[id]);
		printf("Filozof nr %d podniosl widelec nr %d\n", id, id);
		sem_wait(&forks[tmpid]);
		printf("Filozof nr %d podniosl widelec nr %d\n", id, tmpid);		
	}
}

void put_forks(int id) {		
	int tmpid = (id + 1)%phil_count;
	printf("Filozof %d odklada widelce %d, %d\n", id, id, tmpid);
	sem_post(&forks[id]);
	sem_post(&forks[tmpid]);
}

void * philosopher(void * id_ptr) {
	int id = *(int *)id_ptr;
	while (1) {
		printf("Filozof nr %d: 'Jestem głodny'\n", id);
		pick_forks(id);
		printf("Filozof nr %d: 'Jem'\n", id);
		sleep(2);
		put_forks(id);
		printf("Filozof nr %d: 'Zjadlem'\n", id);
		sleep(2);
	}
}

int main(int argc, char ** argv) {
	int i;
	for (i = 0; i < phil_count; i++) {
		if (sem_init(&forks[i], 0, 1) < 0) {
			perror("sem_init");
			return -1;
		}
	}
	if (sem_init(&mutex, 0, 1) < 0) {
		perror("sem_init");
		return -2;
	}
	pthread_t threads[phil_count];
	for (i = 0; i < phil_count; i++) {
		if (pthread_create(&threads[i], NULL, philosopher, &i) == -1) {
			perror("pthread_create");
			return -3;
		}
	}
	for (i = 0; i < phil_count; i++) {
		if (pthread_join(threads[i], NULL) == -1) {
			perror("pthread_join");
			return -3;
		}
	}
	for (i = 0; i < phil_count; i++) {
		sem_destroy(&forks[i]);
	}
	sem_destroy(&mutex);
	return 0;
}
